<?php


namespace custom;

use house\HouseCount1;
use think\Db;

class ImportHouse {


    /**
     * 导入数据
     * @var
     */
    protected $data;
    /**
     * 导入配置验证
     * @var
     */
    protected $config;
    /**
     * 导入字段
     * @var mixed
     */
    protected $importField;
    /**
     * 导入字段key、value替换
     * @var mixed
     */
    protected $importFieldFlip;
    /**
     * 导入字段名字
     * @var mixed
     */
    protected $importFieldName;
    /**
     * 操作者
     * @var
     */
    protected $userId;
    /**
     * 导入每行数据
     * @var
     */
    protected $importItem;
    /**
     * 错误信息
     * @var
     */
    protected $errMsg = [];
    /**
     * 导入纪录id
     * @var
     */
    protected $importId;

    protected $city_code;

    public function __construct($file, $config, $userId, $city_code) {
        $this->file = $file;
        $this->config = $config;
        $this->importField = config('export.import_field');
        $this->importFieldFlip = array_flip($this->importField);
        $this->importFieldName = config('export.export_field_name');
        $this->userId = $userId;
        $this->city_code = $city_code;
    }

    /**
     * 数据导入
     * @return bool
     */
    public function import() {
        // 文件验证
        if (!verifyFile($this->file, $this->config)) {
            return false;
        }
        // 导入
        $importData = importCsv($this->file['tmp_name']);
        if (!$importData) {
            return false;
        }

        $head = $importData['head'];
        $this->data = $importData['data'];


        if (!$this->verifyHead($head)) {
            return false;
        }
        $totalNum = count($this->data);

        if (!$this->addImportLog($totalNum)) {
            Err::add('导入失败');
        }
        $this->importData();
        return true;
    }

    /**
     * 头部验证
     * @param $head
     * @return bool
     */
    protected function verifyHead($head) {
        // 配置head
        $headConfig = [];
        foreach ($this->importField as $field) {
            !empty($this->importFieldName[$field]) && $headConfig[] = $this->importFieldName[$field];
        }
        if ($headConfig != $head) {
            Err::add('导入数据头部错误');
            return false;
        }
        return true;
    }

    /**
     * 添加导入日志
     * @param $totalNum
     * @return int|string
     */
    protected function addImportLog($totalNum) {
        $data = [
            'name'      => $this->file['name'],
            'total_num' => $totalNum,
            'err_num'   => 0,
            'user_id'   => $this->userId,
            'itime'     => time(),
            'status'    => 0,
            'city_code' => $this->city_code,
        ];
        $this->importId = db('import_log')->insertGetId($data);
        return $this->importId;
    }

    /**
     * 导入数据
     */
    protected function importData() {
        $isErr = false;
        foreach ($this->data as $key => $data) {
            $item = $this->verifyData($data);
            if ($item) {
                // 导入房源表
                db('house')->where('id', $item['id'])->strict(false)->update($item);
                unset($item['id']);
                if (isset($item['location'])) {
                    unset($item['location']);
                }
                // 导入房源拍卖表
                db('house_auction')->where('id', $item['auction_id'])->strict(false)->update($item);

                // 统计套数
                $houseCount1 = new HouseCount1();
                $houseCount1((string)$item['id'], (array)$item);

//                if ($item['is_shelf'] == 1 && isset($item['business_area_id']) && isset($item['city_code'])) {
//                    $this->staticNumber($item['business_area_id'], $item['city_code'], $item['old_business_area_id'], $item['old_city_code']);
//                }
            }

            // 不是最后一条，并且错误条数大于等于500时
            if (count($this->errMsg) >= 500) {
                if ($this->importErrLog()) {
                    $isErr = true;
                    $this->errMsg = [];
                }
            }
        }

        if (!empty($this->errMsg)) {
            $isErr = true;
            $this->importErrLog();
        }

        !$isErr && db('import_log')->where('id', $this->importId)->update(['status' => 2]);
    }

    /**
     * 统计套数
     * @param $businessId 商圈id
     * @param $adCode 区域id
     * @param $oldBusinessId 旧商圈id
     * @param $oldAdCode 旧区域id
     * @throws \think\Exception
     */
    protected function staticNumber($businessId, $adCode, $oldBusinessId, $oldAdCode) {
        // 商圈
        if ($adCode != $oldAdCode) {
            db('region')->where('city_code', $adCode)->setInc('house_number');
            if (!empty($oldAdCode)) {
                db('region')->where('house_number', '>', 0)->where('city_code', $oldAdCode)->setDec('house_number');
            }
        }
        // 区域
        if ($businessId != $oldBusinessId) {
            db('business_area')->where('id', $businessId)->setInc('house_number');
            if (!empty($oldBusinessId)) {
                db('business_area')->where('house_number', '>', 0)->where('id', $oldBusinessId)->setDec('house_number');
            }
        }
    }

    /**
     * 验证数据
     * @param $data
     * @return array|bool
     */
    protected function verifyData($data) {
        $this->importItem = $data;
        $item = [];
        // 房源id
        $id = $this->getData('id');
        $hData = db('house')->field('auction_id,id,is_shelf,city_code,business_area_id,source_city')
            ->where('id', $id)
            ->find();
        if (empty($hData)) {
            $this->errMsg[] = $this->setErrMsg($id, 'id', '不存在');
            return false;
        }
        $auData = Db('house_auction')
            ->field('initial_price,auction_status')
            ->where('id', $hData['auction_id'])
            ->find();
        if (empty($auData)) {
            $this->errMsg[] = $this->setErrMsg($id, 'id', '不存在对应的拍卖信息，请联系开发');
            return false;
        }
        $item['old_business_area_id'] = $hData['business_area_id'];
        $item['old_city_code'] = $hData['city_code'];
        $item['is_shelf'] = $hData['is_shelf'];
        $item['auction_id'] = $hData['auction_id'];
        $item['id'] = $id;
        $item['auction_status'] = $auData['auction_status'];
        // 房屋类型一级
        $houseType = $this->getData('house_type');
        $item['house_type'] = db('house_type')->where('name', $houseType)->value('id');
        if (empty($item['house_type'])) {
            $this->errMsg[] = $this->setErrMsg($id, 'house_type', '未知');
            return false;
        }
        // 房屋类型二级
        $houseCateArr = array_flip(config('export.house_cate'));
        $houseCate = $this->getData('house_cate');
        if (!isset($houseCateArr[$houseCate])) {
            $this->errMsg[] = $this->setErrMsg($id, 'house_cate', '未知');
            return false;
        }
        $item['house_cate'] = $houseCateArr[$houseCate];
        // 产权类型
        $propertyTypeArr = array_flip(config('export.property_type'));
        $propertyType = $this->getData('property_type');
        if (!isset($propertyTypeArr[$propertyType])) {
            $this->errMsg[] = $this->setErrMsg($id, 'property_type', '未知');
            return false;
        }
        $item['property_type'] = $propertyTypeArr[$propertyType];
        // 小区名字
        $hvName = $this->getData('hv_name');

        if (!empty($hvName)) {
            $vField = 'id,business_area,address,province,city,area,lng,lat,city_code,city_codes';
            $hvName = replaceSpecialChar($hvName);
            $cy = str_replace('市', '', $hData['source_city']);
            $vData = db('house_village')
                ->field($vField)
                ->where('city', 'like', $cy . '%')
                ->where('name', $hvName)
                ->find();
            if (empty($vData)) {
                $this->errMsg[] = $this->setErrMsg($id, 'hv_name', '不存的');
                return false;
            }
            $item['village_id'] = $vData['id'];
            $item['business_area_id'] = $vData['business_area'];
            $item['address'] = $vData['address'];
            $item['province'] = $vData['province'];
            $item['city'] = $vData['city'];
            $item['area'] = $vData['area'];
            $item['lng'] = $vData['lng'];
            $item['lat'] = $vData['lat'];
            $item['location'] = Db::raw("POINT('{$vData['lng']}', '{$vData['lat']}')");
            $item['city_code'] = $vData['city_code'];
            $item['city_codes'] = $vData['city_codes'];
        }

        // 建筑年代
        $buildTime = $this->getData('build_time');
        if (!empty($buildTime)) {
            if (!preg_match("/^[1-9][0-9]{3}$/", $buildTime)) {
                $this->errMsg[] = $this->setErrMsg($id, 'build_time', '格式错误');
                return false;
            }
            $item['build_time'] = $buildTime;
        }

        // 建筑面积
        $buildArea = $this->getData('build_area');
        if (!empty($buildArea)) {
            if (!preg_match("/^[0-9]{1,5}(\.[0-9]{1,4})?$/", $buildArea)) {
                $this->errMsg[] = $this->setErrMsg($id, 'build_area', '格式错误');
                return false;
            }
            $item['build_area'] = $buildArea * 10000;
        }

        // 户型
        $doorModel = $this->getData('door_model');
        if ($doorModel != '') {
            $doorModel = str_replace('室', 's', $doorModel);
            $doorModel = str_replace('厅', 't', $doorModel);
            if (!preg_match("/^([0-9]{1,2})s([0-9]{1,2})t$/", $doorModel, $arr)) {
                $this->errMsg[] = $this->setErrMsg($id, 'door_model', '格式错误');
                return false;
            }
            $item['bedroom'] = $arr[1];
            $item['livingroom'] = $arr[2];
        }

        // 装修
        $renovationType = $this->getData('renovation_type');
        if ($renovationType != '') {
            $renovationTypeArr = array_flip(config('export.renovation_type'));
            if (!isset($renovationTypeArr[$renovationType])) {
                $this->errMsg[] = $this->setErrMsg($id, 'renovation_type', '未知');
                return false;
            }
            $item['renovation_type'] = $renovationTypeArr[$renovationType];
        }

        // 楼层
        $floor = $this->getData('floor');
        if ($floor != '') {
            if (!is_numeric($floor)) {
                $this->errMsg[] = $this->setErrMsg($id, 'floor', '格式错误');
                return false;
            }
            $item['floor'] = $floor;
        }

        // 最高楼层
        $maxFloor = $this->getData('max_floor');
        if ($maxFloor != '') {
            if (!is_numeric($maxFloor)) {
                $this->errMsg[] = $this->setErrMsg($id, 'max_floor', '格式错误');
                return false;
            }
            $item['max_floor'] = $maxFloor;
        }

        // 权证号
        $item['warrant'] = $this->getData('warrant');

        // 居住情况
        $livingType = $this->getData('living_type');
        if ($livingType != '') {
            $livingTypeArr = array_flip(config('export.living_type'));
            if (!isset($livingTypeArr[$livingType])) {
                $this->errMsg[] = $this->setErrMsg($id, 'living_type', '未知');
                return false;
            }
            $item['living_type'] = $livingTypeArr[$livingType];
        }

        // 市场评估价
        $marketPrice = $this->getData('market_price');
        $marketPrice = str_replace(',', '', $marketPrice);
        $item['discount'] = -1;
        if (!empty($marketPrice)) {
            if (!preg_match("/^[0-9]{1,12}(\.[0-9]{1,2})?$/", $marketPrice)) {
                $this->errMsg[] = $this->setErrMsg($id, 'market_price', '格式错误');
                return false;
            }
            $item['market_price'] = moneyFormat($marketPrice);
            // 当初始价 小于等于市场价时，才计算折扣
            if ($auData['initial_price'] < $item['market_price']) {
                $item['discount'] = round($auData['initial_price'] / $item['market_price'] * 10, 2);
                $item['discount'] < 1 && $item['discount'] = 0;
                $item['discount'] >= 10 && $item['discount'] = 10;
            }
        }

        // 安居客地址
        $item['anjuke_url'] = $this->getData('anjuke_url');

        // 安居客平均价
        $anjukePrice = $this->getData('anjuke_price');
        $anjukePrice = str_replace(',', '', $anjukePrice);
        if (!empty($anjukePrice)) {
            if (!preg_match("/^[0-9]{1,8}(\.[0-9]{1,2})?$/", $anjukePrice)) {
                $this->errMsg[] = $this->setErrMsg($id, 'anjuke_price', '格式错误');
                return false;
            }
            $item['anjuke_price'] = moneyFormat($anjukePrice);
        }

        // 是否有电梯
        $lifts = $this->getData('lifts');
        if ($lifts != '') {
            $liftsArr = array_flip(config('export.lifts'));
            if (!isset($liftsArr[$lifts])) {
                $this->errMsg[] = $this->setErrMsg($id, 'lifts', '未知');
                return false;
            }
            $item['lifts'] = $liftsArr[$lifts];
        }

        // 尾款缴付日期
        $item['tail_money_date'] = $this->getData('tail_money_date');

        // 其它数据
        $item['is_update'] = 1;
        $item['utime'] = time();
        $item['bulu_time'] = strtotime(date('Y-m-d', time()));
        return $item;
    }

    /**
     * 获取指定字段的值
     * @param $field
     * @return mixed
     */
    protected function getData($field) {
        return $this->importItem[$this->importFieldFlip[$field]];
    }

    /**
     * 错误日志
     * @param $id
     * @param $msg
     * @param $field
     * @return array
     */
    protected function setErrMsg($id, $field, $msg) {
        return [
            'import_id' => $this->importId,
            'house_id'  => $id,
            'msg'       => $this->importFieldName[$field] . $msg,
        ];
    }

    /**
     * 纪录错误信息
     * @return int|string
     */
    protected function importErrLog() {

        $iData = [
            'status' => 1,
        ];
        $count = count($this->errMsg);
        db('import_log')->where('id', $this->importId)->inc('err_num', $count)->update($iData);
        return db('import_err_log')->insertAll($this->errMsg);
    }
}
